#include "mystdio.h"
#include <cstring>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

My_File *BuyFile(int fd, int flag)
{
    My_File *file = (My_File *)malloc(sizeof(My_File));
    file->fd = fd;
    file->buffer_len = 0;
    file->flush_method = LINE_FLUSH;
    file->flag = flag;
    memset(file->buffer, 0, sizeof(file->buffer));
    return file;
}

My_File *MyFopen(const char *path, const char *mode)
{
    int flag = 0;
    int fd = 0;
    if (mode == nullptr || path == nullptr)
    {
        return nullptr;
    }
    if (strcmp(mode, "w") == 0)
    {
        flag = O_CREAT | O_WRONLY | O_TRUNC;
        fd = open(path, flag, 0666);
    }
    else if (strcmp(mode, "r") == 0)
    {
        flag = O_RDONLY;
        fd = open(path, flag, 0666);
    }
    else if (strcmp(mode, "a") == 0)
    {
        flag = O_APPEND | O_CREAT | O_WRONLY;
        fd = open(path, flag, 0666);
    }
    else
    {
        return nullptr;
    }
    return BuyFile(fd, flag);
}

void MyFclose(My_File *file)
{
    MyFFlush(file);
    close(file->fd);
    free(file);
    return;
}

int MyFwrite(My_File *file, void *str, int len)
{
    if (len < MAX)
    {
        memcpy(file->buffer, str, len);
        file->buffer_len = len - 1;
        file->buffer[len] = 0;
    }
    else
    {
        memcpy(file->buffer, str, MAX);
        file->buffer_len = MAX - 1;
        file->buffer[MAX] = 0;
    }

    if ((file->flush_method == LINE_FLUSH) && (file->buffer[len - 1] == '\n'))
        MyFFlush(file);
    return file->buffer_len;
}

void MyFFlush(My_File *file)
{
    if (file->buffer_len < 0)
    {
        return;
    }
    write(file->fd, file->buffer, file->buffer_len);
    file->buffer_len = 0;
    fsync(file->fd);
    return;
}
